home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / pmake / prefix / xdr.c < prev   
Encoding:
C/C++ Source or Header  |  1989-11-15  |  9.5 KB  |  413 lines

  1. /***********************************************************************
  2.  *
  3.  * PROJECT:      PMake
  4.  * MODULE:      Prefix -- XDR routines
  5.  * FILE:      xdr.c
  6.  *
  7.  * AUTHOR:        Adam de Boor: Jul  4, 1989
  8.  *
  9.  * ROUTINES:
  10.  *    Name              Description
  11.  *    ----              -----------
  12.  *    xdr_fattr           serialize file attributes
  13.  *    xdr_attrstat        serialize RFS_GETATTR result
  14.  *    xdr_srok            serialize NFS_OK part of RFS_READLINK result
  15.  *    xdr_rdlnres         serialize RFS_READLINK result
  16.  *    xdr_fsok            serialize NFS_OK part of RFS_STATFS result
  17.  *    xdr_statfs          serialize RFS_STATFS result
  18.  *    xdr_diropargs        serialize struct nfsdiropargs
  19.  *    xdr_drok            serialize NFS_OK part of directory operation
  20.  *                        result.
  21.  *    xdr_diropres        serialize directory operation result
  22.  *    xdr_rddirargs        serialize RFS_READDIR args
  23.  *    xdr_putrddirres        serialize RFS_READDIR result
  24.  *
  25.  * REVISION HISTORY:
  26.  *    Date      Name        Description
  27.  *    ----      ----        -----------
  28.  *    7/ 4/89      ardeb        Initial version
  29.  *
  30.  * DESCRIPTION:
  31.  *    XDR translation routines for this beastie
  32.  *
  33.  *    All these routines are snarfed from the source for an
  34.  *    NFS kernel:
  35.  *
  36.  *     Copyright (c) 1986 Sun Microsystems, Inc.
  37.  *
  38.  *    Additional Notice:
  39.  *    
  40.  *     Permission to use, copy, modify, and distribute this
  41.  *     software and its documentation for any non-commercial purpose
  42.  *    and without fee is hereby granted, provided that the above copyright
  43.  *     notice appears in all copies.  Neither Berkeley Softworks nor
  44.  *     Adam de Boor makes any representations about the suitability of this
  45.  *     software for any purpose.  It is provided "as is" without
  46.  *     express or implied warranty.
  47.  *
  48.  ***********************************************************************/
  49. #ifndef lint
  50. static char *rcsid =
  51. "$Id: xdr.c,v 1.2 89/07/08 19:36:06 adam Exp $";
  52. #endif lint
  53.  
  54. #include <stdio.h>
  55. #include <rpc/rpc.h>
  56. #include <sys/time.h>
  57. #include <sys/errno.h>
  58. #include <sys/vfs.h>
  59. #include <nfs/nfs.h>
  60. #include <rpcsvc/mount.h>
  61. #include <sys/dir.h>
  62.  
  63. /*
  64.  * File attributes
  65.  */
  66. bool_t
  67. xdr_fattr(xdrs, na)
  68.     XDR *xdrs;
  69.     register struct nfsfattr *na;
  70. {
  71.     register long *ptr;
  72.  
  73.     if (xdrs->x_op == XDR_ENCODE) {
  74.         ptr = XDR_INLINE(xdrs, 17 * BYTES_PER_XDR_UNIT);
  75.         if (ptr != NULL) {
  76.             IXDR_PUT_ENUM(ptr, na->na_type);
  77.             IXDR_PUT_LONG(ptr, na->na_mode);
  78.             IXDR_PUT_LONG(ptr, na->na_nlink);
  79.             IXDR_PUT_LONG(ptr, na->na_uid);
  80.             IXDR_PUT_LONG(ptr, na->na_gid);
  81.             IXDR_PUT_LONG(ptr, na->na_size);
  82.             IXDR_PUT_LONG(ptr, na->na_blocksize);
  83.             IXDR_PUT_LONG(ptr, na->na_rdev);
  84.             IXDR_PUT_LONG(ptr, na->na_blocks);
  85.             IXDR_PUT_LONG(ptr, na->na_fsid);
  86.             IXDR_PUT_LONG(ptr, na->na_nodeid);
  87.             IXDR_PUT_LONG(ptr, na->na_atime.tv_sec);
  88.             IXDR_PUT_LONG(ptr, na->na_atime.tv_usec);
  89.             IXDR_PUT_LONG(ptr, na->na_mtime.tv_sec);
  90.             IXDR_PUT_LONG(ptr, na->na_mtime.tv_usec);
  91.             IXDR_PUT_LONG(ptr, na->na_ctime.tv_sec);
  92.             IXDR_PUT_LONG(ptr, na->na_ctime.tv_usec);
  93.             return (TRUE);
  94.         }
  95.     } else {
  96.         ptr = XDR_INLINE(xdrs, 17 * BYTES_PER_XDR_UNIT);
  97.         if (ptr != NULL) {
  98.             na->na_type = IXDR_GET_ENUM(ptr, enum nfsftype);
  99.             na->na_mode = IXDR_GET_LONG(ptr);
  100.             na->na_nlink = IXDR_GET_LONG(ptr);
  101.             na->na_uid = IXDR_GET_LONG(ptr);
  102.             na->na_gid = IXDR_GET_LONG(ptr);
  103.             na->na_size = IXDR_GET_LONG(ptr);
  104.             na->na_blocksize = IXDR_GET_LONG(ptr);
  105.             na->na_rdev = IXDR_GET_LONG(ptr);
  106.             na->na_blocks = IXDR_GET_LONG(ptr);
  107.             na->na_fsid = IXDR_GET_LONG(ptr);
  108.             na->na_nodeid = IXDR_GET_LONG(ptr);
  109.             na->na_atime.tv_sec = IXDR_GET_LONG(ptr);
  110.             na->na_atime.tv_usec = IXDR_GET_LONG(ptr);
  111.             na->na_mtime.tv_sec = IXDR_GET_LONG(ptr);
  112.             na->na_mtime.tv_usec = IXDR_GET_LONG(ptr);
  113.             na->na_ctime.tv_sec = IXDR_GET_LONG(ptr);
  114.             na->na_ctime.tv_usec = IXDR_GET_LONG(ptr);
  115.             return (TRUE);
  116.         }
  117.     }
  118.     if (xdr_enum(xdrs, (enum_t *)&na->na_type) &&
  119.         xdr_u_long(xdrs, &na->na_mode) &&
  120.         xdr_u_long(xdrs, &na->na_nlink) &&
  121.         xdr_u_long(xdrs, &na->na_uid) &&
  122.         xdr_u_long(xdrs, &na->na_gid) &&
  123.         xdr_u_long(xdrs, &na->na_size) &&
  124.         xdr_u_long(xdrs, &na->na_blocksize) &&
  125.         xdr_u_long(xdrs, &na->na_rdev) &&
  126.         xdr_u_long(xdrs, &na->na_blocks) &&
  127.         xdr_u_long(xdrs, &na->na_fsid) &&
  128.         xdr_u_long(xdrs, &na->na_nodeid) &&
  129.         xdr_timeval(xdrs, &na->na_atime) &&
  130.         xdr_timeval(xdrs, &na->na_mtime) &&
  131.         xdr_timeval(xdrs, &na->na_ctime) ) {
  132.         return (TRUE);
  133.     }
  134.     return (FALSE);
  135. }
  136.  
  137. struct xdr_discrim attrstat_discrim[2] = {
  138.     { (int)NFS_OK, xdr_fattr },
  139.     { __dontcare__, NULL_xdrproc_t }
  140. };
  141.  
  142. /*
  143.  * Reply status with file attributes
  144.  */
  145. bool_t
  146. xdr_attrstat(xdrs, ns)
  147.     XDR *xdrs;
  148.     struct nfsattrstat *ns;
  149. {
  150.  
  151.     if (xdr_union(xdrs, (enum_t *)&(ns->ns_status),
  152.           (caddr_t)&(ns->ns_attr), attrstat_discrim, xdr_void) ) {
  153.         return (TRUE);
  154.     }
  155.     return (FALSE);
  156. }
  157.  
  158. /*
  159.  * NFS_OK part of read sym link reply union
  160.  */
  161. bool_t
  162. xdr_srok(xdrs, srok)
  163.     XDR *xdrs;
  164.     struct nfssrok *srok;
  165. {
  166.  
  167.     if (xdr_bytes(xdrs, &srok->srok_data, (u_int *)&srok->srok_count,
  168.         NFS_MAXPATHLEN) ) {
  169.         return (TRUE);
  170.     }
  171.     return (FALSE);
  172. }
  173.  
  174. struct xdr_discrim rdlnres_discrim[2] = {
  175.     { (int)NFS_OK, xdr_srok },
  176.     { __dontcare__, NULL_xdrproc_t }
  177. };
  178.  
  179. /*
  180.  * Result of reading symbolic link
  181.  */
  182. bool_t
  183. xdr_rdlnres(xdrs, rl)
  184.     XDR *xdrs;
  185.     struct nfsrdlnres *rl;
  186. {
  187.  
  188.     if (xdr_union(xdrs, (enum_t *)&(rl->rl_status),
  189.           (caddr_t)&(rl->rl_srok), rdlnres_discrim, xdr_void) ) {
  190.         return (TRUE);
  191.     }
  192.     return (FALSE);
  193. }
  194.  
  195. /*
  196.  * NFS_OK part of statfs operation
  197.  */
  198. xdr_fsok(xdrs, fsok)
  199.     XDR *xdrs;
  200.     struct nfsstatfsok *fsok;
  201. {
  202.  
  203.     if (xdr_long(xdrs, (long *)&fsok->fsok_tsize) &&
  204.         xdr_long(xdrs, (long *)&fsok->fsok_bsize) &&
  205.         xdr_long(xdrs, (long *)&fsok->fsok_blocks) &&
  206.         xdr_long(xdrs, (long *)&fsok->fsok_bfree) &&
  207.         xdr_long(xdrs, (long *)&fsok->fsok_bavail) ) {
  208.         return (TRUE);
  209.     }
  210.     return (FALSE);
  211. }
  212.  
  213. struct xdr_discrim statfs_discrim[2] = {
  214.     { (int)NFS_OK, xdr_fsok },
  215.     { __dontcare__, NULL_xdrproc_t }
  216. };
  217.  
  218. /*
  219.  * Results of statfs operation
  220.  */
  221. xdr_statfs(xdrs, fs)
  222.     XDR *xdrs;
  223.     struct nfsstatfs *fs;
  224. {
  225.  
  226.     if (xdr_union(xdrs, (enum_t *)&(fs->fs_status),
  227.           (caddr_t)&(fs->fs_fsok), statfs_discrim, xdr_void) ) {
  228.         return (TRUE);
  229.     }
  230.     return (FALSE);
  231. }
  232.  
  233. /*
  234.  * Arguments for directory operations
  235.  */
  236. bool_t
  237. xdr_diropargs(xdrs, da)
  238.     XDR *xdrs;
  239.     struct nfsdiropargs *da;
  240. {
  241.  
  242.     if (xdr_fhandle(xdrs, &da->da_fhandle) &&
  243.         xdr_string(xdrs, &da->da_name, NFS_MAXNAMLEN) ) {
  244.         return (TRUE);
  245.     }
  246.     return (FALSE);
  247. }
  248.  
  249. /*
  250.  * NFS_OK part of directory operation result
  251.  */
  252. bool_t
  253. xdr_drok(xdrs, drok)
  254.     XDR *xdrs;
  255.     struct nfsdrok *drok;
  256. {
  257.  
  258.     if (xdr_fhandle(xdrs, &drok->drok_fhandle) &&
  259.         xdr_fattr(xdrs, &drok->drok_attr) ) {
  260.         return (TRUE);
  261.     }
  262.     return (FALSE);
  263. }
  264.  
  265. struct xdr_discrim diropres_discrim[2] = {
  266.     { (int)NFS_OK, xdr_drok },
  267.     { __dontcare__, NULL_xdrproc_t }
  268. };
  269.  
  270. /*
  271.  * Results from directory operation 
  272.  */
  273. bool_t
  274. xdr_diropres(xdrs, dr)
  275.     XDR *xdrs;
  276.     struct nfsdiropres *dr;
  277. {
  278.  
  279.     if (xdr_union(xdrs, (enum_t *)&(dr->dr_status),
  280.           (caddr_t)&(dr->dr_drok), diropres_discrim, xdr_void) ) {
  281.         return (TRUE);
  282.     }
  283.     return (FALSE);
  284. }
  285.  
  286. /*
  287.  * Arguments to readdir
  288.  */
  289. bool_t
  290. xdr_rddirargs(xdrs, rda)
  291.     XDR *xdrs;
  292.     struct nfsrddirargs *rda;
  293. {
  294.  
  295.     if (xdr_fhandle(xdrs, &rda->rda_fh) &&
  296.         xdr_u_long(xdrs, &rda->rda_offset) &&
  297.         xdr_u_long(xdrs, &rda->rda_count) ) {
  298.         return (TRUE);
  299.     }
  300.     return (FALSE);
  301. }
  302.  
  303. /*
  304.  * Directory read reply:
  305.  * union (enum status) {
  306.  *    NFS_OK: entlist;
  307.  *        boolean eof;
  308.  *    default:
  309.  * }
  310.  *
  311.  * Directory entries
  312.  *    struct  direct {
  313.  *        u_long  d_fileno;           * inode number of entry *
  314.  *        u_short d_reclen;           * length of this record *
  315.  *        u_short d_namlen;           * length of string in d_name *
  316.  *        char    d_name[MAXNAMLEN + 1];  * name no longer than this *
  317.  *    };
  318.  * are on the wire as:
  319.  * union entlist (boolean valid) {
  320.  *     TRUE: struct dirent;
  321.  *          u_long nxtoffset;
  322.  *           union entlist;
  323.  *    FALSE:
  324.  * }
  325.  * where dirent is:
  326.  *     struct dirent {
  327.  *        u_long    de_fid;
  328.  *        string    de_name<NFS_MAXNAMELEN>;
  329.  *    }
  330.  */
  331.  
  332. #define    nextdp(udp)    ((struct direct *)((int)(udp) + DIRSIZ(udp)))
  333.  
  334. /*
  335.  * ENCODE ONLY
  336.  *
  337.  *             MODIFIED FROM KERNEL VERSION:
  338.  *
  339.  * The offset return is an entry index, rather than a position.
  340.  */
  341. bool_t
  342. xdr_putrddirres(xdrs, rd)
  343.     XDR *xdrs;
  344.     struct nfsrddirres *rd;
  345. {
  346.     struct direct *udp;
  347.     char *name;
  348.     int size;
  349.     int xdrpos;
  350.     u_int namlen;
  351.     u_long offset;
  352.     bool_t true = TRUE;
  353.     bool_t false = FALSE;
  354.  
  355.     if (xdrs->x_op != XDR_ENCODE) {
  356.         return (FALSE);
  357.     }
  358.     if (!xdr_enum(xdrs, (enum_t *)&rd->rd_status)) {
  359.         return (FALSE);
  360.     }
  361.     if (rd->rd_status != NFS_OK) {
  362.         return (TRUE);
  363.     }
  364.  
  365.     dprintf("xdr_putrddirres:\n");
  366.  
  367.     xdrpos = XDR_GETPOS(xdrs);
  368.     for (size = rd->rd_size, udp = rd->rd_entries;
  369.          size > 0;
  370.          size -= udp->d_reclen, udp = nextdp(udp)) {
  371.         dprintf("\t%s(%d) size = %d\n", udp->d_name, udp->d_fileno,
  372.             size);
  373.  
  374.         /*
  375.          * Pre-increment the offset since the client will want to
  376.          * have the offset it should use for the next call, while
  377.          * rd->rd_offset contains the offset it would need to
  378.          * fetch the current entry.
  379.          */
  380.  
  381.         offset = ++rd->rd_offset;
  382.  
  383.         if (udp->d_reclen == 0 || DIRSIZ(udp) > udp->d_reclen) {
  384.             return (FALSE);
  385.         }
  386.         if (udp->d_fileno == 0) {
  387.             continue;
  388.         }
  389.         name = udp->d_name;
  390.         namlen = udp->d_namlen;
  391.         if (!xdr_bool(xdrs, &true) ||        /* valid */
  392.             !xdr_u_long(xdrs, &udp->d_fileno) ||    /* fileno */
  393.             !xdr_bytes(xdrs, &name, &namlen, NFS_MAXNAMLEN) ||/*name*/
  394.             !xdr_u_long(xdrs, &offset) ) { /* always final offset */
  395.             return (FALSE);
  396.         }
  397.         if (XDR_GETPOS(xdrs) - xdrpos >= rd->rd_bufsize) {
  398.             rd->rd_eof = FALSE;
  399.             break;
  400.         }
  401.     }
  402.     /*
  403.      * Signal end of entries by providing a false valid field
  404.      */
  405.     if (!xdr_bool(xdrs, &false)) {
  406.         return (FALSE);
  407.     }
  408.     if (!xdr_bool(xdrs, &rd->rd_eof)) {
  409.         return (FALSE);
  410.     }
  411.     return (TRUE);
  412. }
  413.